package javachess;



import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class GamePanel extends JPanel implements MouseListener, KeyListener, Runnable
{
	public static class Map
	{
		int[][] slot = new int[8][8];
		
		public void init()
		{
			for (int i = 0; i < 2; ++i)
				for (int j = 0; j < 8; ++j)
					slot[i][j] = 0; // 0 is player 1
			for (int i = 2; i < 6; ++i)
				for (int j = 0; j < 8; ++j)
					slot[i][j] = 2; // 2 is empty
			for (int i = 6; i < 8; ++i)
				for (int j = 0; j < 8; ++j)
					slot[i][j] = 1; // 1 is player 2
		}
	}
	
	Vector<Piece> v = new Vector<Piece>();
	Vector<Player> players = new Vector<Player>();
	
	public static void main(String[] args)
	{
		JFrame jf = new JFrame("Chess");
		GamePanel gp = new GamePanel();
		jf.add(gp);
		//jf.setSize(600, 600);
		//jf.setSize(328, 352);//for when scale = 5
		jf.setSize((W * S) * 8 + 8, (H * S) * 8 + 34);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jf.setVisible(true);
		gp.requestFocus();
		
		gp.testFunction();
		
		Map gameBoard = new Map();
		gameBoard.init();
	}
	
	public void testFunction()
	{
		players.add(new Player(0, 0x00ff00));
		players.add(new Player(1, 0xff0000));
		selectedPiece = null;
	}
	
	/**
	 * for the game
	 */
	//probably should be in game
	boolean running;

	/**
	 * the width of the board
	 */
	final static int W = 8;
	/**
	 * the height of the board
	 */
	final static int H = 8;
	/**
	 * the scale, so the spaces are bigger
	 */
	final static int S = 10;
	
	int currentPlayer = 0;
	
	Piece selectedPiece;
	
	Point m_loc = new Point();
	//Piece m_piece = new Piece((char)1, 0);
	Piece m_piece = new Piece((char)1, 0);
	Pawn m_pawn = new Pawn(0,0,0);
	
	//Player [] players = new Player(0,0)[2];
	//players = new Player[2];
	//for(int i = 0; i < players.size; ++i)
	//{
	//	players[i] = new Player(0, 0x00ff00);
	//}
	
	/**
	 * This function switches the current player
	 */
	public void endTurn()
	{
		if(currentPlayer == 0)
			currentPlayer = 1;
		else 
			currentPlayer = 0;
		//System.out.println(Integer.toString(currentPlayer));
		
		selectedPiece = null;
	}
	
	/**
	 * Used for getting the other player when validating moves
	 * @return returns the other player
	 */
	public int otherPlayer()
	{
		if(currentPlayer == 0)
			return 1;
		else 
			return 0;
	}
	                               
	
	public void paintComponent(Graphics a_graphics)
	{
		draw(a_graphics);
		//super.paintComponent(a_graphics);
		//String temp = "" + m_pawn.m_icon;
		//a_graphics.drawString(m_pawn.m_name,(int) m_loc.getX(), (int)m_loc.getY());
		//a_graphics.drawString(m_pawn.m_name,(int) m_pawn.m_x, m_pawn.m_x);
		//a_graphics.drawString(Character.toString(m_pawn.m_icon),(int) m_loc.getX(), (int)m_loc.getY());
	}
	/**
	 * constructor for the GamePanel
	 * adds a mouse and key listener
	 * and starts the thread
	 */
	public GamePanel()
	{
		running = true;
		addMouseListener(this);
		addKeyListener(this);
		Thread t = new Thread(this);
		t.start();
	}
	
	/**
	 * This gets called in paintComponent to draw the board, and hopefully
	 * pieces on the board soon
	 * @param g
	 */
	//this probably should be in a game class
	public void draw(Graphics g)
	{
		//yay magic numbers
		for(int y = 0; y < H; ++y)
		{
			for(int x = 0; x < W; ++x)
			{
				//this part draws the board if there isn't a piece on it
				if((x+y) % 2 == 0)
					g.setColor(Color.WHITE);
				else
					g.setColor(Color.BLACK);
				g.fillRect(x*W*S, y*H*S, W*S, H*S);
				
				//this part could be very long
				if(m_pawn.m_x == x && m_pawn.m_y == y)
				{
					//g.setColor(new Color(0x00ff00));
					//this will need to be changed, would be easier
					// if i could make an array of players
					//then it would be player[currentplayer].m_color
					//and no switch statement, which is what i did before
					switch(currentPlayer)
					{
					case 0:	g.setColor(new Color(players.get(currentPlayer).m_color));
					case 1:	g.setColor(new Color(players.get(currentPlayer).m_color));
					}
					
					//g.setFont(new Font("TimesRoman", Font.PLAIN, 40));
					g.setFont(new Font("TimesRoman", Font.PLAIN, W * S));
					//m_pawn.m_icon = 'p';
					m_pawn.m_icon = '+';
					//g.setColor(new Color(player.m_color));
					g.drawString(Character.toString(m_pawn.m_icon), (x*W*S + (int)(1.5 * S)), (y*H*S + (int)(6.5 * S)));//x = 10, y = 25
					//g.fillRect(x*W*S, y*H*S, W*S, H*S);
				}
				
			}
		}
		
//		for(int i = 0; i < v.size(); ++i)
//		{
//			if (v.get(i).m_owner == 0)
//			{
//				g.setColor(Color.RED);
//			}
//			else if (v.get(i).m_owner == 1)
//			{
//				g.setColor(Color.GREEN);
//			}
//			g.setFont(new Font("TimesRoman", Font.PLAIN, 40));
//			m_pawn.m_icon = 'p';
//			//g.setColor(new Color(player.m_color));
//			g.drawString(Character.toString(m_pawn.m_icon), (v.get(i).m_x*W*S + 10), (v.get(i).m_y*H*S + 25));
//		}
		
		//draws the player's pieces
	for(int j = 0; j < players.size(); ++j)
	{
		for(int i = 0; i < players.get(j).m_pieces.size(); ++i)
		{
			players.get(j).m_pieces.get(i).draw(g, W, H, S, players.get(j).m_color);
			//System.out.println(""+player.m_pieces.get(i).m_icon+" "+player.m_pieces.get(i).m_x + " " + player.m_pieces.get(i).m_y);
		}
	}
		//System.out.println("break");
	}
	
	/**
	 * This takes care of key presses, and is called in keyPressed from KeyListener
	 * @param input
	 */
	//this probably should be in a game class
	public void handleInput(int input)
	{
		//temporary code for keeping the square on the board
		//asking for forgiveness
		int oldx = m_pawn.m_x;
		int oldy = m_pawn.m_y;
		
		//handling the input
		switch(input)
		{
		case KeyEvent.VK_W:	m_pawn.m_y--;	break;
		case KeyEvent.VK_A:	m_pawn.m_x--;	break;
		case KeyEvent.VK_S:	m_pawn.m_y++;	break;
		case KeyEvent.VK_D:	m_pawn.m_x++;	break;
		case KeyEvent.VK_O:	endTurn();		break;
		//case KeyEvent.VK_O:	System.out.println(Character.toString(m_pawn.m_icon));break;
		case KeyEvent.VK_Q:
			//so far this just stops the thread, the window stays open
			running = false;
			System.out.println("quitting");
			break;
		}
		
		if(m_pawn.m_x < 0 || m_pawn.m_y < 0 
				|| m_pawn.m_x >= W || m_pawn.m_y >= H)
		{
			m_pawn.m_x = oldx;
			m_pawn.m_y = oldy;
		}
	}
	//////////////////////////////////////////
	 private static int x , y;
	 private static GamePanel object = new GamePanel();
	 
	public void mouseClicked(MouseEvent e){
		 x = e.getX();
		 y = e.getY();
		 object.getLocale();
	}	
	public void drawing(int xx,  int yy)
	{
		x = xx;
		y = yy;
		repaint();
	}
	
	////////////////////////////////////////////
	public void mouseEntered(MouseEvent arg0){}
	public void mouseExited(MouseEvent arg0){}
	public void mousePressed(MouseEvent e)
	{
		if(e.getButton() == 1)
		{
			System.out.println("press "+ (e.getX() / (W * S)) + " " + (e.getY() / (H * S)));
			//this.m_loc.setLocation(e.getX(), e.getY());
			
			processClicked((e.getX() / (W * S)), (e.getY() / (H * S)));
			
			
			if (selectedPiece == null)
			{
			}
			else
				System.out.println(selectedPiece.m_icon);
		}
		else
		{
			selectedPiece = null;
			System.out.println("SELECTION HAS BEEN CLEARED");
		}
		

		//m_piece.m_loc.getX();
		//repaint();
	}
	
	/**
	 * function that decides whether to try to select a piece (if 
	 * selectedPiece is null), or try to move a piece (if selectedPiece
	 * is not null).
	 * @param x
	 * @param y
	 */
	public void processClicked(int x, int y)
	{
		if(selectedPiece == null)
		{
			searchSelectables(x,y);
		}
		else
		{
			boolean itWorked = false;
			
			if(selectedPiece.m_icon == 'r')
			{
				Rook r = (Rook) selectedPiece;
				if (r.validateMove(players.get(currentPlayer), players.get(otherPlayer()), x, y))
					itWorked = true;
			}
			else if(selectedPiece.m_icon == 'p')
			{
				Pawn r = (Pawn) selectedPiece;
				if (r.validateMove(players.get(currentPlayer), players.get(otherPlayer()), x, y))
					itWorked = true;
			}
			else if(selectedPiece.m_icon == 'q')
			{
				Queen r = (Queen) selectedPiece;
				if(r.validateMove(players.get(currentPlayer), players.get(otherPlayer()), x, y))
					itWorked = true;
			}
			else if(selectedPiece.m_icon == 'K')
			{
				King r = (King) selectedPiece;
				if(r.validateMove(players.get(currentPlayer), players.get(otherPlayer()), x, y))
					itWorked = true;
			}
			else if(selectedPiece.m_icon == 'n')
			{
				Knight r = (Knight) selectedPiece;
				if(r.validateMove(players.get(currentPlayer), players.get(otherPlayer()), x, y))
					itWorked = true;
			}
			else if(selectedPiece.m_icon == 'b')
			{
				Bishop r = (Bishop) selectedPiece;
				if(r.validateMove(players.get(currentPlayer), players.get(otherPlayer()), x, y))
					itWorked = true;
			}
			
			if(itWorked)
			{
				for(int i = 0; i < players.get(otherPlayer()).m_pieces.size(); ++i)
				{
					if(players.get(otherPlayer()).m_pieces.get(i).m_x == x
					&& players.get(otherPlayer()).m_pieces.get(i).m_y == y)
					{
						players.get(otherPlayer()).m_pieces.remove(i);
						break;
					}
				}
				selectedPiece.move(x,y);	
				endTurn();
			}
		}
	}
	
	/**
	 * searches through all of the current players pieces to see if
	 * the player clicked on any of their own pieces. this function
	 * only occurs if a piece is NOT already selected.
	 * @param x
	 * @param y
	 */
	public void searchSelectables(int x, int y)
	{
		for (int i = 0; i < players.get(currentPlayer).m_pieces.size(); ++i)
		{
			if(players.get(currentPlayer).m_pieces.get(i).m_x == x
			&& players.get(currentPlayer).m_pieces.get(i).m_y == y)
			{
				selectedPiece = players.get(currentPlayer).m_pieces.get(i);
				break;
			}
			else
			{
				selectedPiece = null;
			}
		}
	}
	
	public void mouseReleased(MouseEvent arg0){}


	public void run()
	{
		//running  = true;
		
		do{
			repaint();
			try
			{
				Thread.sleep(100);
			}catch(Exception e){}
		}while(running);
		System.exit(0);
		
	}

	public void keyPressed(KeyEvent e)
	{
		running = e.getKeyCode() != KeyEvent.VK_Q;
		handleInput(e.getKeyCode());
		
	}
	public void keyReleased(KeyEvent arg0){}
	public void keyTyped(KeyEvent arg0){}
}
